Repository navigation
Z projection 5/6: the run side (part of #176) - #217
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
The manifest records a projection summary for projected copies, RunInputs.projection exposes it, the run warns masks_on_projected_images, and RunInputs refuses a manifest that disagrees with the conversion record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
This was referenced Nov 8, 2026
…n_record_missing) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
# Conflicts: # CHANGELOG.md
The Windows CI job failed: the record restored with write_text gained CRLF line endings, so its SHA-256 no longer matched the run's and RunInputs refused it. Restore the original bytes instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base is
main;origin/main(through #228) is merged in (CHANGELOG anddocs/contract.mdconflicts resolved by keeping both sides), so the diff shows this PR only.What changed
Fifth PR of the plan for #176 (design: MorphoFeature
docs/restart/designs/pp176-z-projection-design-2026-11-07.md, PR 5 and the owner answers: every image goes through the method; 2-D masks are paired with a recorded warning; 3-D masks stop the projection; one optional--z-range).projectionkey (optional, left out for an unprojected run, so that manifest is byte for byte as before):method,z_rangerequested,conversion_record {file, sha256}(the source record, same SHA-256 asconversion_record_sha256),source_root, per analysed imagesource_relative_path,source_content_sha256,source_z_size,z_range(slices used),source_dtype,output_dtype,dtype_rule,rounding,significant_bits_dropped, plusmasks_pairedandwarnings. Read strictly (exact keys, valid method, SHA-256 shape, range inside the size, warnings consistent with masks);manifest_versionis not changed.RunInputs.projection: aRunProjection(method,z_range,conversion_record,source_root,images,image(relative_path),masks_paired,warnings), orNonefor an unprojected run.RunInputs.openrefuses (RunInputsError): a manifest whoseprojectionis not exactly what conversion record v3 gives for the recorded images and masks; projected copies recorded with noprojection; aprojectionwith no conversion record; a record changed or gone. Nothing is read as a plain image.masks_on_projected_imageswarning (names the method, lists the masks) raised inPreflight/check/run, recorded in the manifest, shown in the report. A 3-D mask next to a projected copy still stops the run asmask_planes_mismatch.max projections of slices 1:4 (2 images) of <source>in the text andconversion.projectionindiscovery_report.json(key only for projected copies).projection_run.py,run_inputs_projection.pyandprojection_marker.py(layers declared). Docs: contract §9 (manifest row), §9.1, §17, user guide, CHANGELOG.Owner decisions (2026-11-08)
checkandrunread each analysed TIFF's OMEImage/Description(the first page's description tag; header only).convert --projectwrites projected copies with a description beginning "MorphoBricks Z projection:" (projection_record.MARKER, the same constant the writer uses). An image with that marker, in a tree with no conversion record or whose record does not list it asprojected, is an errorprojection_record_missing: it names the images and says to rerunconvert --projector restore the conversion record. Plain images without the marker are unaffected; nothing is guessed (a non-TIFF, or a header that cannot be read, is not marked).RunInputs.projectionrun-level property: kept.masks_on_projected_images: stays warning-only.Cost of the new check. One TIFF header read per analysed image that the record does not already list as
projected(none for a normal projected tree; one per image for a plain tree). It is the page description tag only: no pixel read is added (a test patchesTiffPage.asarrayto fail and the marker check still passes). An unprojected run is unchanged:tests/test_parity_v0_4_0.pypasses.Regression evidence
tests/test_run_projection.py(11 tests, unchanged): regression for the manifest/RunInputsprojection.tests/test_projection_marker.py(4 tests). The regression istest_projected_copies_without_their_record_are_refused: a projected tree with its record deleted. On the previous branch tip behaviour (check removed) the file gives 1 failed, 3 passed (the tree is accepted); with the check: 4 passed. The other tests: a record that lists the image ascopieddoes not vouch for it; a plain OME-TIFF without the marker is unaffected (noprojection_record_missing, no conversion review); the check reads no pixels.Checks
python tools/check.py: Ruff, format and code rules clean (files at most 600 lines;manifest.pyis 593; no parameter or line baseline grew:to_dict's labels were compacted to stay inside its line baseline);4634 passed, 4 skipped, 754 warnings. The 4 skips are the pre-existing ones (case-insensitive file system x2, x1 more, file modes x1). The 754 warnings are the existing "No experiment description"UserWarning. Before the main merge and this change the same suite gave 4401 passed (main's new tests account for the rest, plus the 4 new here).Not in this series yet
PR 6 (notebook card) and PR 7 (homogeneity key). CellPatcher and MorphoFeature are not edited; they can read
RunInputs.projectiononce this lands.🤖 Generated with Claude Code
https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm